import { HubConnectionBuilder, HubConnectionState, LogLevel } from '@microsoft/signalr';
import store from '../store/store';
import { isNumber, isString ,findIndex, clone} from 'lodash';
var DownloadAllList=[];
export class HubClient {
  constructor(hubUrl) {
    this.hubUrl = hubUrl;
    this.downloadList=[];
    this._statePrev = HubConnectionState.Disconnected;
    this._connection = new HubConnectionBuilder()
      .configureLogging(LogLevel.Warning)
      .withUrl(hubUrl)
      .withAutomaticReconnect({
        nextRetryDelayInMilliseconds: (retryContext) => {
          const { previousRetryCount } = retryContext;
          if (previousRetryCount === 0) {
            // 如果是第一次断线，立即重连
            return 0;
          } else if (previousRetryCount < 5) {
            // 如果尝试重连次数少于5次，使用指数退避策略增加延迟
            // 例如，第1次延迟2秒，第2次延迟4秒，依此类推
            return Math.pow(2, previousRetryCount) * 1000;
          } else {
            // 如果尝试重连次数达到5次或更多，每次尝试之间延迟30秒
            return 30000;
          }
        },
      })
      .build();
    this._connection.onclose((error) => {
      console.info("HubConnection.onclose", error);
      this._nextState();
    });
    this._connection.onreconnecting((error) => {
      console.info("HubConnection.onreconnecting", error);
      this._nextState();
    });
    this._connection.onreconnected((connectionId) => {
      console.info("HubConnection.onreconnected", connectionId);
      this._nextState();
    });
    this._connection.on('OnFileDownloadProcessChanged',this.OnFileDownloadProcessChanged);
    this._connection.on('OnFileDownloadFinished',this.OnFileDownloadFinished);
  }

  get state() {
    return this._connection.state;
  }

  get enable() {
    return this._enable;
  }

  set enable(val) {
    this._enable = !!val;
    if (this._enable) {
      setTimeout(() => {
        this._tryStart();
      }, 0);
    } else {
      setTimeout(() => {
        this._tryStop();
      }, 0);
    }
  }

  /**
   * @overload
   * @param {"OnDeviceConnected"} event
   * @param {(e: {deviceId: string; ip: string; status: string[];}) => any} handler
   * @returns {() => void}
   */
  on(event, handler) {
    const { _connection } = this;
    _connection.on(event, handler);
    return () => _connection.off(event, handler);
  }

  /** @private */
  _nextState() {
    const prev = this._statePrev;
    const next = this._connection.state
    if (prev !== next) {
      this._statePrev = next;
    }
  }

  /** @private */
  _tryStart() {
    if (!this.enable) return;
    if (this._connection.state !== HubConnectionState.Disconnected) return;
    this._connection.start()
      .catch(err => console.error(err))
      .finally(() => {
        this._nextState();
      });
  }

  /** @private */
  _tryStop() {
    if (this.enable) return;
    if (this._connection.state !== HubConnectionState.Connected) return;
    this._connection.stop()
      .catch(err => console.error(err))
      .finally(() => {
        this._nextState();
      });
  }

  _resultDownList(){
    DownloadAllList=[];
    console.log('清空了')
  }

  /* 监听数据 */

  // 下载进度   
  OnFileDownloadProcessChanged(url,progress){
    if(!url || !isString(url)) return;
    // console.log('下载进度',url,progress)
    store.dispatch('resource/setfileDownProgress',{
        progress:progress && isNumber(Number(progress))?Number(progress):0,
        fileUrl:url,
        type:1,
      })
  };

  // 下载完成
  OnFileDownloadFinished(url){
    if(!url || !isString(url)) return;
    let list=clone(store.state.resource.fileDownList);
    DownloadAllList.push(url);
    if(list.length>0){
      let cIndex = findIndex(list, o => o.downloadUri == url);
      if (cIndex >= 0 || url.indexOf('.db')!==-1) {
        list[cIndex].progress = 100
        list[cIndex].type = 2;
      }
      let isDownAll = true;
      list.forEach(item => {
        if (item.type == 1){
          isDownAll = false;
        }
      });
      if(isDownAll || DownloadAllList.length == list.length){
        store.dispatch('resource/setfileDownSuccess',true);
      }
    }
  };
  /* 方法调用 */

  /**
   * 获取联网设备
   * @returns {Promise<ApiResult<DeviceInfo[]>>}
   */
  getDevices() {
    return this._connection.invoke('GetDevices');
  }

  /**
   * 初始化设备状态
   * @param {string[]} clientId
   * @returns {Promise<ApiResult<MNT_STATUSDto[]>>}
   */
  getDevicesStatus(clientId) {
    return this._connection.invoke('GetDevicesStatus', clientId);
  }
}

let apiServerUrl = window.location.origin;
if (process.env.NODE_ENV === "development") {
  apiServerUrl = "http://localhost:34567";
}
const hubClient = new HubClient(apiServerUrl + "/hub/backend");
export default hubClient;
